Skip to content

Python: document keyed web search with Serply MCP - #8319

Open
Serply (googio) wants to merge 2 commits into
microsoft:mainfrom
googio:feat/serply-search
Open

Serply (googio) wants to merge 2 commits into
microsoft:mainfrom
googio:feat/serply-search

Conversation

@googio

Copy link
Copy Markdown

Motivation & Context

The MCP README has an anonymous web search example (Parallel, #8084) and a generic header_provider sample, but no runnable example of a keyed web search server that combines the two. This adds one for the Serply MCP server, which exposes Google, Bing, Google News, Google Scholar, Google Maps, and page scraping tools behind an X-Api-Key header.

The example reuses the header_provider pattern from mcp_api_key_auth.py, so the key is scoped to api.serply.io requests, and calls the tools directly so it needs no model provider account.

I work with Serply, which operates this service.

Description & Review Guide

  • What are the major changes? One new README section after the Parallel example: dependency installation, tool discovery, and direct google_search and google_news_search calls through MCPStreamableHTTPTool with header_provider. One line under Prerequisites for SERPLY_API_KEY.
  • What is the impact of these changes? Documentation only. No code, dependencies, providers, or defaults change. Readers who do not set SERPLY_API_KEY are unaffected.
  • What do you want reviewers to focus on? Whether the section reads as complementary to the anonymous Parallel example. One note for the changelog: the code block works against main (it needs the ambient header_provider handshake fix from Python: preserve MCP request ownership on low-level sends #8246). Against the released agent-framework-core 1.18.0 wheel with mcp 1.30 the initialize request goes out without the header and Serply answers 401, so the example will start working for wheel users with the next release.

Verification: ran the exact code block from the README with agent-framework-core installed from this branch and a live key. Output listed the nine Serply tools, three web results with title, URL, and snippet, and a list of news articles. Ran ruff check and ruff format --check on the snippet with the repo config. No non-ASCII characters were added.

Related Issue

None. This follows the shape of #8084, which added the Parallel section without an issue.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The documentation is internally consistent, scoped appropriately, and provides a complete runnable example.

Pull request overview

Adds a documentation-only Serply MCP example demonstrating authenticated web and news search without a model provider account.

Changes:

  • Documents dependency installation and SERPLY_API_KEY setup.
  • Adds direct google_search and google_news_search calls using host-scoped header_provider.
  • Describes available tools, output, data transmission, and connection cleanup.
File summaries
File Description
python/samples/02-agents/mcp/README.md Adds the keyed Serply MCP walkthrough and prerequisite.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@googio

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Add a README section to the MCP samples showing MCPStreamableHTTPTool
against the Serply MCP server with header_provider supplying the
X-Api-Key header, calling google_search and google_news_search directly.
Adds the SERPLY_API_KEY line under Prerequisites.
Comment thread python/samples/02-agents/mcp/README.md Outdated
The key is fixed for the process, so static_headers is the right API. A
header_provider holds _call_headers_lock for the whole call_tool, which
would serialize concurrent Serply searches; static_headers keeps the same
origin scoping and cross-origin redirect stripping without that lock.
@eavanvalkenburg

Copy link
Copy Markdown
Member

Thanks for the update. Before this is ready, could you please:

Once those are addressed, please re-request review. Thanks!

@googio

Serply (googio) commented Sep 14, 2026

Copy link
Copy Markdown
Author

Thanks, done. The README.md:99 discussion is resolved.

For the record, since it went outdated before it was read: moonbox3 asked for static_headers={"X-Api-Key": api_key} in place of header_provider, and that was the right call. The key is read once from the environment and never varies per run, so it has no business on the dynamic path, where call_tool holds _call_headers_lock for the duration of every call and would stop an agent from running Serply searches concurrently. static_headers keeps the origin scoping and the cross-origin redirect stripping that the sample wanted in the first place. Shipped in dc5b686, along with a reworded paragraph that says why, and the pointer to mcp_api_key_auth.py now reads as the example to follow when the header value does depend on the run. I reran the snippet verbatim against the live server afterwards: nine tools listed, three web results, the news list.

One judgement call I made rather than leave hanging, easy to reverse if you disagree. static_headers arrived in #8285 on 11 Sep and is not in python-1.18.0, which is still the newest agent-framework-core on PyPI, so the pip install agent-framework-core line in this section will not run the snippet until the next Python release ships. I have left that line as it is, on the assumption that samples track main and the release will land well before anyone trips over it. If you would rather it were explicit, say the word and I will add a one-line version note in the next push.

That leaves it ready for another look. I cannot press re-request review myself: from an outside fork the API answers FORBIDDEN for RequestReviews, so the button is yours rather than mine. Could one of you re-request on my behalf when it suits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants